#ifndef __DTH11_H__
#define __DTH11_H__


#include <stdio.h>
#include <wiringPi.h>
#include <time.h>
#include <stdlib.h>

typedef unsigned char uchar;

class DTH11{
	
	char DTH_sense;
	int count;
	float HUM_value;
	float TEM_value;

public:
	DTH11(char pin) 
	: DTH_sense(pin),count(0),HUM_value(0), TEM_value(0)
	{}

	//初始化 开启DTH11
	void start()
	{
		pinMode(DTH_sense, OUTPUT);
		digitalWrite(DTH_sense,0);
		delayMicroseconds(5);
	   digitalWrite(DTH_sense,1); //发送一个高电平脉冲
	   delayMicroseconds(2);
	   
	   digitalWrite(DTH_sense,0); //拉低延时
	   delay(20);   //延时18ms以上
	   
	   digitalWrite(DTH_sense,1);
	   delayMicroseconds(30); //主机拉高20~40us
	   
	   //digitalWrite(DTH_sense,0);
	   pinMode(DTH_sense, INPUT);
	}

	//从DTH11接收一个字节
	uchar DHT11_rec_byte() 
	{
	   uchar i,dat={0};
	  for(i=0;i<8;i++)    //从高到低依次接收8位数据
	   {          //每个bit之前有50us低电平
		 while(digitalRead(DTH_sense)==0)
		 {++count;if(count>=65536){printf("error1\n");return -1;}}; count=0;   //等待50us低电平过去
		  delayMicroseconds(30);     //延时30us，如果还为高则数据为1，否则为0 
		  dat<<=1;           //移位使正确接收8位数据，数据为0时直接移位
		  if(digitalRead(DTH_sense))    //数据为1时，使dat加1来接收数据1
			 {dat+=1;}
		  while(digitalRead(DTH_sense)==1)
		  {++count;if(count>=100000){printf("error2\n");return -1;}};count=0;  //等待数据线拉低    
		}  
		return dat;
	}

	//接收40位的数据
	int receive()     
	{
		uchar H_H=0, H_L=0, T_H=0, T_L=0,revise=0; 
		
		this->start();
		
			count=0;while(digitalRead(DTH_sense)==1)
	{++count;if(count>=65536){printf("error3\n");return 0;}};count=0; 
			count=0;while(digitalRead(DTH_sense)==0);   //等待DTH拉高
	   {++count;if(count>=65536){printf("error4\n");return 0;}};count=0; 
			count=0;while(digitalRead(DTH_sense)==1);  //拉高后延时80us,进入数据传输
	{++count;if(count>=65536){printf("error5\n");return 0;}};count=0; 
			
			if( (H_H=DHT11_rec_byte())==-1) return 0;    //接收湿度高八位  
			if( (H_L=DHT11_rec_byte())==-1) return 0;    //接收湿度低八位  
			if( (T_H=DHT11_rec_byte())==-1) return 0;    //接收温度高八位  
			if( (T_L=DHT11_rec_byte())==-1) return 0;    //接收温度低八位
			if( (revise=DHT11_rec_byte())==-1) return 0; //接收校正位

			if((H_H+H_L+T_H+T_L)==revise)      //校正
			{
				HUM_value = (int)(H_H)+(float)((int)(H_L))/100;
				TEM_value = (int)(T_H)+(float)((int)(T_L))/100;
			} 
			
			delayMicroseconds(25);    //结束
			  return 1;
	}
	
	float getHumValue(void)
	{
		return HUM_value;
	}
	
	float getTemValue(void)
	{
		return TEM_value;
	}
	
	//---------------------------application
	void show(int delay_time)
	{
		time_t curtime;
		while(1){
			delay(delay_time);
			time(&curtime);
			printf("当前时间: %s",ctime(&curtime));
			
			if(!receive()) continue; 
			else
			{
				printf("HUM: %.2f %% RH\n",HUM_value);
				printf("TEM: %.2f ^C\n",TEM_value);
			}
		}
	}

};
#endif
